package com.yunju.xuexin.xuexincrawler.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yunju.xuexin.xuexincrawler.Model.ProxyModel;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import javax.net.ssl.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.*;

public class OkhttpManager {
	static private OkhttpManager mOkhttpManager = null;
	private InputStream mTrustrCertificate;

//	private static List<ProxyModel>

	static public OkhttpManager getInstance() {
		return new OkhttpManager();
	}

	private KeyStore newEmptyKeyStore(char[] password)
			throws GeneralSecurityException {
		try {
			KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
			InputStream in = null; // By convention, 'null' creates an empty key
									// store.
			keyStore.load(in, password);
			return keyStore;
		} catch (IOException e) {
			throw new AssertionError(e);
		}
	}

	private X509TrustManager trustManagerForCertificates(InputStream in)
			throws GeneralSecurityException {
		CertificateFactory certificateFactory = CertificateFactory
				.getInstance("X.509");
		Collection<? extends Certificate> certificates = certificateFactory
				.generateCertificates(in);
		if (certificates.isEmpty()) {
			throw new IllegalArgumentException(
					"expected non-empty set of trusted certificates");
		}

		// Put the certificates a key store.
		char[] password = "password".toCharArray(); // Any password will work.
		KeyStore keyStore = newEmptyKeyStore(password);
		int index = 0;
		for (Certificate certificate : certificates) {
			String certificateAlias = Integer.toString(index++);
			keyStore.setCertificateEntry(certificateAlias, certificate);
		}

		// Use it to build an X509 trust manager.
		KeyManagerFactory keyManagerFactory = KeyManagerFactory
				.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		keyManagerFactory.init(keyStore, password);
		TrustManagerFactory trustManagerFactory = TrustManagerFactory
				.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		trustManagerFactory.init(keyStore);
		TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
		if (trustManagers.length != 1
				|| !(trustManagers[0] instanceof X509TrustManager)) {
			throw new IllegalStateException(
					"Unexpected default trust managers:"
							+ Arrays.toString(trustManagers));
		}
		return (X509TrustManager) trustManagers[0];
	}

	public void setTrustrCertificates(InputStream in) {
		mTrustrCertificate = in;
	}

	public InputStream getTrustrCertificates() {
		return mTrustrCertificate;
	}

	public OkHttpClient build(final Map<String, List<Cookie>> cookieStore,ProxyModel proxyModel) {
		OkHttpClient okHttpClient = null;
		Builder builder = new OkHttpClient.Builder();
		builder.cookieJar(new CookieJar() {

			public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
				cookieStore.put(url.host(), cookies);
			}

			public List<Cookie> loadForRequest(HttpUrl url) {
				List<Cookie> cookies = cookieStore.get(url.host());
				return cookies != null ? cookies : new ArrayList<Cookie>();
			}
		});

		if (getTrustrCertificates() != null) {
			X509TrustManager trustManager;
			SSLSocketFactory sslSocketFactory;
			try {
				trustManager = trustManagerForCertificates(getTrustrCertificates());
				SSLContext sslContext = SSLContext.getInstance("TLS");
				sslContext
						.init(null, new TrustManager[] { trustManager }, null);
				sslSocketFactory = sslContext.getSocketFactory();
			} catch (GeneralSecurityException e) {
				throw new RuntimeException(e);
			}
			okHttpClient = builder.sslSocketFactory(sslSocketFactory,
					trustManager)
					.retryOnConnectionFailure(false)
					.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyModel.getHost(), proxyModel.getPort()))).build();
		} else {
			okHttpClient = builder
					.retryOnConnectionFailure(false).proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyModel.getHost(), proxyModel.getPort()))).build();
		}
		return okHttpClient;
	}


	public static List<ProxyModel> freshProxy(){
		String freshUrl = "http://http-webapi.zhimaruanjian.com/getip?num=2&type=2&pro=&city=0&yys=0&port=1&pack=6240&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1";
		try {
			Document document = Jsoup.connect(freshUrl).get();
			String docContent = document.text();

			JSONObject docJson = JSON.parseObject(docContent);
			JSONArray docArr = docJson.getJSONArray("data");
			return  JSONObject.parseArray(docArr.toJSONString(),ProxyModel.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String args[]){
		System.out.println(JSON.toJSONString(freshProxy()));
		System.out.println(   Math.random()*10000);
	}

}